#include <iostream>
#include <stdexcept>
#include <string>
#include <fstream>
#include "item.h"
#include "itemfactory.h"
#include <boost/archive/binary_oarchive.hpp>                               
#include <boost/archive/binary_iarchive.hpp>
using namespace std;

ItemFactory::ItemFactory(){
	item_ = 0;
}

ItemFactory::~ItemFactory(){
	delete item_;
}

// Change the id of an already existing blueprint
void ItemFactory::setId(string id){
	item_->setId(id);

}

// Change the name of an already existing blueprint
void ItemFactory::setName(string name){
	item_->setName(name);
}

// Change the description of an already existing blueprint
void ItemFactory::setDescription(string desc){
	item_->setDescription(desc);
}

// Change the picture name of an already existing blueprint
void ItemFactory::setPicName(string picname){
	//picname = "adventure2/graphics/items/" + picname;
	item_->setPicName(picname);
}

// Create a new item blueprint
void ItemFactory::create(string id) throw (itemfactory_error){

	string itemFile = "adventure2/items/" + id + ".add";
	const char* file = itemFile.c_str();
	fstream load(file, ios::in|ios::binary);

	if(!load)
	{
		item_ = new Item();
		item_->setId(id);
		//save();
	}
	else
	{
		throw itemfactory_error("itemfactory: Blueprint does already exist!");
	}
	
	load.close();
	
}

// Creates an item object from a blueprint and returns it
Item* ItemFactory::build(string id) throw(itemfactory_error){
	Item* item;
	string filename = "adventure2/items/" + id + ".add";
	const char* file = filename.c_str();
	fstream load(file, ios::in|ios::binary);
	
	// Load item if the file exists
	if(load)
	{
		ifstream ifs(file);
		boost::archive::binary_iarchive ia(ifs);
		ia >> item;
	}
	else
	{
		throw itemfactory_error("itemfactory: Could not build item!");
	}	

	return item;
}

// Save changes made to blueprint
void ItemFactory::save(){
	string filename = "adventure2/items/" + item_->getId() + ".add";
	const char* file = filename.c_str();
	
	// Clear the file
	fstream savetofile(file, ios::out|ios::binary|ios::trunc);	
	savetofile.close();

	// Save the item object
	{
		ofstream ofs(file);
		boost::archive::binary_oarchive oa(ofs);
		oa << item_;
	}
}

// Load a blueprint
void ItemFactory::load(string id){
	// Get path to file
	string filename = "adventure2/items/" + id + ".add";
	const char* file = filename.c_str();
	fstream load(file, ios::in|ios::binary);
	
	// Load item if the file exists
	if(load)
	{
		Item* garbage = item_;
		item_ = 0;
		delete garbage;

		ifstream ifs(file);
		boost::archive::binary_iarchive ia(ifs);
		ia >> item_;
	}
	else
	{
		throw itemfactory_error("itemfactory: Blueprint does not exist!");
	}
	
	load.close();
}

void ItemFactory::delItem() throw(itemfactory_error)
{
	
	if(item_ != 0)
	{
		// Get the path to the file and delete it
		string filename = "adventure2/items/" + item_->getId() + ".add";
		const char* file = filename.c_str();
		remove(file);
		
		// Remove the object we are working with
		Item *garbage = item_;
		item_ = 0;
		delete garbage;
	}
	else
	{
		throw itemfactory_error("itemfactory: Tried to delete a null pointer!");
	}

}
